import { useEffect, useRef, useState } from "react";
import styles from './index.less';
import { Slider, Segmented } from "antd";
import AMapView, { AMapRef } from '@/components/AMapView';

import concaveman from 'concaveman';
import * as turf from '@turf/turf';

import pointsYuHua from '@/assets/map/points-qinghai.json';
import pointsNanJing from '@/assets/map/points-nanjing.json';
import pointsQingHai from '@/assets/map/points-qinghai.json';

const tabs = [{label: '原始', value: 'origin'}, {label: '凹包', value: 'hull'}, {label: '边缘简化', value: 'simplify'}];

const marks = {
    1: {label: '1', style: {color: 'white'}},
    2: {label: '2', style: {color: 'white'}},
    3: {label: '3', style: {color: 'white'}},
    4: {label: '4', style: {color: 'white'}},
    5: {label: '5', style: {color: 'white'}},
    6: {label: '6', style: {color: 'white'}},
    7: {label: '7', style: {color: 'white'}},
    8: {label: '8', style: {color: 'white'}},
    9: {label: '9', style: {color: 'white'}},
    10: {label: '10', style: {color: 'white'}},
};

const marks2 = {
    0: {label: '0', style: {color: 'white'}},
    0.1: {label: '0.1', style: {color: 'white'}},
    0.2: {label: '0.2', style: {color: 'white'}},
    0.3: {label: '0.3', style: {color: 'white'}},
    0.4: {label: '0.4', style: {color: 'white'}},
    0.5: {label: '0.5', style: {color: 'white'}},
    0.6: {label: '0.6', style: {color: 'white'}},
    0.7: {label: '0.7', style: {color: 'white'}},
    0.8: {label: '0.8', style: {color: 'white'}},
    0.9: {label: '0.9', style: {color: 'white'}},
    1: {label: '1', style: {color: 'white'}},
};

const marks3 = {
    0: {label: '0', style: {color: 'white'}},
    0.01: {label: '0.01', style: {color: 'white'}},
    0.02: {label: '0.02', style: {color: 'white'}},
    0.03: {label: '0.03', style: {color: 'white'}},
    0.04: {label: '0.04', style: {color: 'white'}},
    0.05: {label: '0.05', style: {color: 'white'}},
};

// 原始数据
const originData: any[] = [];
pointsNanJing.forEach(i => {
    originData.push([i[1], i[0]]);
});

const getMarkerContent = () => {
    const color = '#1876ff';
    const content =
        `<div style="width: 6px; height: 6px; background-color: ${color}; border-radius: 3px;">` +
        `</div>`;
    return content;
};

export default () => {
    const mapRef = useRef<AMapRef>(null);
    const polygonsRef = useRef<any>(null);
    const markersRef = useRef<any>(null);
    const isMapInit = useRef<boolean>(false);

    const [dataType, setDataType] = useState<'origin' | 'hull' | 'simplify'>('origin');
    const [data, setData] = useState<any[]>(originData);

    // 凹面
    const [concavity, setConcavity] = useState<number>(2);
    // 长度阈值
    const [lengthThreshold, setLengthThreshold] = useState<number>(0);
    // 容差
    const [tolerance, setTolerance] = useState<number>(0.01);
    // 面积误差
    const [areaDeviation, setAreaDeviation] = useState<number>(0);

    useEffect(() => {

    }, []);

    useEffect(() => {
        if (!isMapInit.current) {
            return;
        }

        let newData: any[] = []
        if (dataType == 'origin') {
            newData = originData;
        } else if (dataType == 'hull') {
            const hull = concaveman(originData, concavity, lengthThreshold);
            newData = hull;
        } else if (dataType == 'simplify') {
            const turfPolygon = (turf.polygon([originData]));
            const simplified = turf.simplify(turfPolygon, {tolerance, highQuality: false});
            newData = simplified.geometry.coordinates[0];
        }
        setData(newData);
        drawPolygon(newData);
    }, [dataType]);

    useEffect(() => {
        if (!isMapInit.current) {
            return;
        }

        let newData: any[] = []
        if (dataType == 'hull') {
            const hull = concaveman(originData, concavity, lengthThreshold);
            newData = hull;
        } else if (dataType == 'simplify') {
            const turfPolygon = (turf.polygon([originData]));
            const simplified = turf.simplify(turfPolygon, {tolerance, highQuality: false});
            newData = simplified.geometry.coordinates[0];
        }
        setData(newData);
        drawPolygon(newData);
    }, [concavity, lengthThreshold, tolerance]);

    useEffect(() => {
        const originPolygon = (turf.polygon([originData]));
        const originArea = turf.area(originPolygon);

        const dataPolygon = (turf.polygon([data]));
        const dataArea = turf.area(dataPolygon);
        const errorPercent = ((dataArea - originArea) / originArea) * 100;
        setAreaDeviation(Math.abs(errorPercent));
    }, [data]);

    const drawPolygon = (_data: any[]) => {
        if (polygonsRef.current) {
            mapRef.current?.removePolyline(polygonsRef.current);
        }
        if (markersRef.current) {
            mapRef.current?.removeMarker(markersRef.current);
        }
        const polygon = new AMap.Polygon({
            path: [[_data]], //多边形路径
            fillColor: "#ff6991", //多边形填充颜色
            strokeOpacity: 1, //线条透明度
            fillOpacity: 0.5, //填充透明度
            strokeColor: "#ff1856", //线条颜色
            strokeWeight: 2, //线条宽度
        });
        polygonsRef.current = polygon;
        mapRef.current?.addPolyline(polygon);

        if (_data.length < 2000) {
            let markerList = _data.map((item) => {
                const marker = new AMap.Marker({
                    position: new AMap.LngLat(item[0], item[1]),
                    content: getMarkerContent(),
                    anchor: 'center',
                    offset: new AMap.Pixel(0, 0),
                    id: item?.id,
                });
                return marker;
            });
            markersRef.current = markerList;
            mapRef.current?.addMarker(markerList);
        }
    }

    return (
        <div className={styles.container}>
            <AMapView
                ref={mapRef}
                height={'100%'}
                zoom={9.5}
                // zoom={6.8}
                zooms={[3, 15]}
                onLoadComplete={() => {
                    isMapInit.current = true;
                    mapRef.current?.setCenter([118.788012, 31.93]);
                    // mapRef.current?.setCenter([96.119494,35.8]);
                    drawPolygon(data);
                }}
            />

            <div className={styles.infoLayout}>
                <p className={styles.originCount}>原始点数: {originData.length}</p>
                <p className={styles.count}>
                    优化点数: {dataType == 'origin' ? '--' : `${data.length || 0} ↓ ${(100 - data.length / originData.length * 100).toFixed(1)}%`}
                </p>
                <p className={styles.count}>
                    面积误差: {dataType == 'origin' ? '--' : areaDeviation < 0.01 ? `${(areaDeviation * 100).toFixed(2)}/万分` : areaDeviation < 0.1 ? `${(areaDeviation * 10).toFixed(2)}/千分` : `${areaDeviation.toFixed(2)}/百分`}
                </p>

                <div className={styles.buttonsLayout}>
                    <Segmented<string>
                        options={tabs}
                        onChange={(value) => {
                            setDataType(value as any);
                        }}
                    />
                </div>

                {(dataType === 'hull') && (
                    <div className={styles.hullLayout}>
                        凹面度
                        <Slider
                            min={1}
                            max={10}
                            defaultValue={5}
                            marks={marks}
                            step={0.1}
                            onChange={(value: number) => {
                                setConcavity(value);
                            }}
                            value={concavity}
                        />

                        长度阈值
                        <Slider
                            min={0}
                            max={1}
                            defaultValue={0}
                            marks={marks2}
                            step={0.01}
                            onChange={(value: number) => {
                                setLengthThreshold(value);
                            }}
                            value={lengthThreshold}
                        />
                    </div>
                )}

                {(dataType === 'simplify') && (
                    <div className={styles.hullLayout}>
                        容差
                        <Slider
                            min={0}
                            max={0.05}
                            defaultValue={0.01}
                            marks={marks3}
                            step={0.0001}
                            onChange={(value: number) => {
                                setTolerance(value);
                            }}
                            value={tolerance}
                        />
                    </div>
                )}
            </div>
        </div>
    );
}
